package com.ac.service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ac.model.AuthMenu;
import com.ac.model.AuthRole;
import com.ac.model.AuthUser;
import com.ac.util.TreeUtil;

import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class AuthMenuService {

	private final AuthRoleService RoleService;

	final MongoTemplate mongo;

	public List<AuthMenu> list() {
		return mongo.findAll(AuthMenu.class);
	}

	@Transactional(rollbackFor = Exception.class)
	public void insert(AuthMenu menu) {
		menu.insert();
		mongo.insert(menu);
	}

	@Transactional(rollbackFor = Exception.class)
	public void update(AuthMenu menu) {
		menu.update();
		Criteria criteria = Criteria.where("_id").is(menu.getId());
		Query query = Query.query(criteria);
		Update update = new Update();
		update.set("parentId", menu.getParentId());
		update.set("title", menu.getTitle());
		update.set("url", menu.getUrl());
		update.set("sort", menu.getSort());
		update.set("type", menu.getType());
		update.set("desc", menu.getDesc());
		update.set("nav", menu.isNav());
		update.set("icon", menu.getIcon());
		update.set("iconName", menu.getIconName());
		update.set("iconFill", menu.getIconFill());
		update.set("updateTime", menu.getUpdateTime());
		mongo.updateFirst(query, update, AuthMenu.class);
	}

	@Transactional(rollbackFor = Exception.class)
	public void remove(AuthMenu menu) {

		// 移除自己
		mongo.remove(menu);

		// 移除所有子节点
		List<String> removeList = TreeUtil.removeId(menu, AuthMenu.class);
		removeList.add(menu.getId());

		// 移除角色管理menu列表
		Update update = new Update().pullAll("menuList", removeList.toArray(new String[removeList.size()]));
		mongo.updateMulti(Query.query(Criteria.where("id").exists(true)), update, AuthRole.class);

	}

	public List<AuthMenu> menuList(AuthUser authUser) {
		List<AuthRole> roleList = RoleService.roleList(authUser, new Document("status", true));
		Set<String> menuIdList = new HashSet<String>();
		for (AuthRole authRole : roleList) {
			for (String menuId : authRole.getMenuList()) {
				menuIdList.add(menuId);
			}
		}

		Criteria criteria = Criteria.where("_id").in(menuIdList);
		Query query = Query.query(criteria);

		List<AuthMenu> list = mongo.find(query, AuthMenu.class);
		return list;
	}
}
